package core

import (
	"fmt"
	"log"
	"os"
	"path/filepath"
	"runtime"
	"tads/server/core/sdk"
	"time"

	"github.com/sirupsen/logrus"
	"gorm.io/gorm"
)

var levelColors = map[logrus.Level]string{
	logrus.DebugLevel: "\033[36m", // Cyan
	logrus.InfoLevel:  "\033[32m", // Green
	logrus.WarnLevel:  "\033[33m", // Yellow
	logrus.ErrorLevel: "\033[31m", // Red
	logrus.FatalLevel: "\033[31m",
	logrus.PanicLevel: "\033[31m",
}

// 数据库日志记录结构（PostgreSQL优化版）
type LogEntry struct {
	gorm.Model
	Level     string    `gorm:"type:varchar(10)"` // PostgreSQL使用varchar而不是size
	Message   string    `gorm:"type:text"`
	Timestamp time.Time `gorm:"type:timestamp"`
	File      string    `gorm:"type:varchar(255)"`
	Line      int       `gorm:"type:integer"`
}

// 数据库钩子结构（无需修改结构，只需修改底层实现）
type DatabaseHook struct {
	db *gorm.DB
}

// 日志配置结构
type Config struct {
	EnableConsole bool
	EnableFile    bool
	EnableDB      bool
	Color         bool
	FileLocation  string
}
type Logger struct {
	*logrus.Logger
	config Config
	db     *gorm.DB
}

func NewLogger(config Config) (*Logger, error) {
	logger := logrus.New()
	logger.SetFormatter(&logrus.TextFormatter{
		FullTimestamp:   true,
		TimestampFormat: "2006-01-02 15:04:05",
		ForceColors:     config.Color,
	})

	l := &Logger{
		Logger: logger,
		config: config,
	}

	if config.EnableFile {
		if err := l.setupFileOutput(); err != nil {
			return nil, err
		}
	}

	if config.EnableDB {
		if err := l.setupDatabase(); err != nil {
			return nil, err
		}
		logger.AddHook(&DatabaseHook{db: l.db})
	}

	if config.Color {
		l.setupColorFormatter()
	}

	return l, nil
}

func (l *Logger) setupFileOutput() error {
	dir := filepath.Dir(l.config.FileLocation)
	if err := os.MkdirAll(dir, 0755); err != nil {
		return fmt.Errorf("create log directory failed: %v", err)
	}

	file, err := os.OpenFile(l.config.FileLocation, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	if err != nil {
		return fmt.Errorf("open log file failed: %v", err)
	}

	l.Logger.SetOutput(file)
	return nil
}

func (l *Logger) setupDatabase() error {
	l.db = sdk.Runtime.GetGorm("postgres")
	if sdk.Runtime.GetGorm("postgres") == nil {
		log.Printf("数据库失败\n")
		return fmt.Errorf("数据库失败\n")
	}
	if err := sdk.Runtime.GetGorm("postgres").AutoMigrate(&LogEntry{}); err != nil {
		return fmt.Errorf("database migration failed: %v", err)
	}
	return nil
}

func (l *Logger) setupColorFormatter() {
	l.Logger.SetFormatter(&logrus.TextFormatter{
		FullTimestamp:   true,
		TimestampFormat: "2006-01-02 15:04:05",
		ForceColors:     true,
		DisableColors:   false,
		CallerPrettyfier: func(f *runtime.Frame) (string, string) {
			filename := filepath.Base(f.File)
			return "", fmt.Sprintf(" %s:%d", filename, f.Line)
		},
	})
}

// 实现数据库钩子接口
func (hook *DatabaseHook) Levels() []logrus.Level {
	return logrus.AllLevels
}

func (hook *DatabaseHook) Fire(entry *logrus.Entry) error {
	logEntry := LogEntry{
		Level:     entry.Level.String(),
		Message:   entry.Message,
		Timestamp: entry.Time,
	}

	if entry.HasCaller() {
		logEntry.File = fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line)
	}

	return hook.db.Create(&logEntry).Error
}

// // 使用示例
// func main() {
// 	config := Config{
// 		EnableConsole: true,
// 		EnableFile:    true,
// 		EnableDB:      true,
// 		Color:         true,
// 		FileLocation:  "./logs/app.log",
// 		DBConfig: DBConfig{
// 			DSN: "user:password@tcp(localhost:3306)/logs?charset=utf8mb4&parseTime=True&loc=Local",
// 		},
// 	}

// 	logger, err := NewLogger(config)
// 	if err != nil {
// 		panic(err)
// 	}

// 	logger.Info("This is an info message")
// 	logger.Warn("This is a warning message")
// 	logger.Error("This is an error message")
// }
